/*
* 附加功能：
*	1. 去重keys，精炼切片
 */
package hash

import (
	"asy-cache-center/nettool"
	"log"
	"net/http"
	"sort"
	"time"
)

// 定时任务
func (m *ConsitentMap) TimeWork() {
	// 每十分钟任务
	hourTicker := time.NewTicker(time.Minute * 10)
	go func() {
		for range hourTicker.C {
			m.Duplicate()
		}
	}()

	// 每1分钟任务
	minTicker := time.NewTicker(time.Minute * 1)
	go func() {
		for range minTicker.C {
			m.PollingSurvive()
		}
	}()
}

// 去重节点
func (m *ConsitentMap) Duplicate() {
	m.Lock()
	defer m.Unlock()
	if len(m.Keys) == 0 {
		return
	}
	mirror := make([]int, 0)
	sort.Ints(m.Keys) // 排序
	mirror = append(mirror, m.Keys[0])
	for i := 1; i < len(m.Keys); i++ { // 去重
		if m.Keys[i-1] == m.Keys[i] {
			continue
		}
		mirror = append(mirror, m.Keys[i])
	}
	m.Keys = mirror
}

// 轮询节点查看是否存活，已经死亡就加入待删除名单
func (m *ConsitentMap) PollingSurvive() {
	m.Lock()
	defer m.Unlock()
	if len(m.Keys) == 0 {
		return
	}
	mirror := make([]int, 0)
	// 超时时间：2秒
	client := &http.Client{Timeout: 5 * time.Second}
	for k, v := range m.NodeMap { // 轮询
		first := nettool.SurviveAlive(client, v+"/alive") // 第一次查询
		if !first {                                       // 稍等一下再查询
			time.Sleep(time.Millisecond * 5)
		}
		if first || nettool.SurviveAlive(client, v+"/alive") { // 两次请求
			mirror = append(mirror, k)
		} else {
			log.Println("[LOG_PollingSurvive] 警告服务已掉线 -", v)
			delete(m.NodeMap, k)
		}
	}
	m.Keys = mirror
}
